package com.medicine.manage.block;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.medicine.manage.block.entity.WeBaseResult;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

@Service
public class WeBASEUtils {

    private static final Logger logger = LoggerFactory.getLogger(WeBASEUtils.class);

    @Value("${fisco-bcos.webase-url}")
    private String webaseUrl;

    @Value("${fisco-bcos.weBase-deploy}")
    private String webaseDeploy;

    @Value("${fisco-bcos.webase-baseUrl}")
    private String  webaseBaseUrl;



    public static final String ABI = IOUtil.readResourceAsString("abi/MedicineController.abi");

    public static final String BIN = IOUtil.readResourceAsString("bin/MedicineController.bin");

    public static final String SET_OPTION_ROLE = "setOptionRole";

    /**
     * 发送 post 请求调用链接口
     * @param userAddress
     * @param contractAddress
     * @param funcName
     * @param funcParam
     * @return 请求结果
     */
    public String funcPost(String userAddress, String contractAddress, String funcName, List funcParam) {

        String dataString = this.createWebaseFrontCallData(userAddress,contractAddress, funcName, funcParam);
        StringEntity entity = this.createEntity(dataString);
        HttpPost httpPost = createHttpPost(webaseUrl, entity);
        // 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 执行http的post请求
        CloseableHttpResponse httpResponse;
        String result = null;
        try {
            logger.debug(funcName + " : " + funcParam);
            httpResponse = httpClient.execute(httpPost);
            result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
            logger.debug(funcName + " : " + result);
            System.out.println(funcName + " : " + result);
        } catch (IOException e) {
            logger.error(funcName + " : error");
            System.out.println(funcName + " : error" );
            e.printStackTrace();
        }
        return result;
    }

    public int getBlockNum(){
        HttpGet httpGet = new HttpGet(webaseBaseUrl + "1/web3/blockNumber");
        // 设置请求头 发送的是json数据格式
        httpGet.setHeader("Content-type", "application/json;charset=utf-8");
        // 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 执行http的post请求
        CloseableHttpResponse httpResponse;
        int result = 0;
        try {
            httpResponse = httpClient.execute(httpGet);
            result = Integer.parseInt(EntityUtils.toString(httpResponse.getEntity(), "UTF-8"));

        } catch (IOException e) {

        }
        return result;
    }

    public String getNodeStatusList(){
        HttpGet httpGet = new HttpGet(webaseBaseUrl + "1/web3/getNodeStatusList");
        // 设置请求头 发送的是json数据格式
        httpGet.setHeader("Content-type", "application/json;charset=utf-8");
        // 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 执行http的post请求
        CloseableHttpResponse httpResponse;
        String result = "";
        try {
            httpResponse = httpClient.execute(httpGet);
            result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");

        } catch (IOException e) {

        }
        return result;
    }


    /**
     *
     * @param signUserId
     * @param contractName
     * @param funcParam
     * @return
     */
    public String deploy(String signUserId, String contractName, List funcParam) {

        String dataString = this.createDeployCallData(signUserId, contractName, funcParam);
        StringEntity entity = this.createEntity(dataString);
        HttpPost httpPost = createHttpPost(webaseDeploy, entity);
        // 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 执行http的post请求
        CloseableHttpResponse httpResponse;
        String result = null;
        try {
            httpResponse = httpClient.execute(httpPost);
            result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
            System.out.println(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }




    public HttpPost createHttpPost(String url, StringEntity entity){
        // 创建post请求方式实例
        HttpPost httpPost = new HttpPost(url);
        // 设置请求头 发送的是json数据格式
        httpPost.setHeader("Content-type", "application/json;charset=utf-8");

        // 把请求消息实体塞进去
        httpPost.setEntity(entity);
        return httpPost;
    }

    public StringEntity createEntity(String data){
        // 设置参数---设置消息实体 也就是携带的数据
        StringEntity entity = new StringEntity(data, Charset.forName("UTF-8"));
        // 设置编码格式
        entity.setContentEncoding("UTF-8");
        // 发送Json格式的数据请求
        entity.setContentType("application/json");
        return entity;
    }

    public String createWebaseFrontCallData(String usignUserId, String contractAddress,String funcName, List funcParam){
        JSONArray abiJSON = JSONUtil.parseArray(ABI);
        JSONObject data = JSONUtil.createObj();

        data.set("signUserId", usignUserId);
        data.set("contractAddress", contractAddress);
        data.set("funcName", funcName);
        data.set("contractAbi", abiJSON);
        data.set("funcParam", funcParam);

        data.set("groupId", "1");
        data.set("useCns", false);
        return JSONUtil.toJsonStr(data);
    }


    public String createDeployCallData(String signUserId, String contractName, List funcParam){
        JSONObject data = JSONUtil.createObj();
        JSONArray abiJSON = JSONUtil.parseArray(ABI);
        data.set("contractName", contractName);
        data.set("abiInfo",abiJSON);
        data.set("bytecodeBin", BIN);
        data.set("funcParam", funcParam);
        data.set("groupId", 1);
        data.set("signUserId", signUserId);
        return JSONUtil.toJsonStr(data);
    }


    public WeBaseResult convertResult(String str){
        WeBaseResult result = JSON.parseObject(str, WeBaseResult.class);
        return result;
    }

    public WeBaseResult convertViewResult(String str){
        WeBaseResult result =new WeBaseResult();
        JSONArray array = JSONUtil.parseArray(str);
        String resultStr = array.getStr(0);
        if(resultStr.startsWith("Call contract return error")){
            result.setStatusOK(false);
            result.setMessage(resultStr);
        } else {
            JSONObject jsonObject = JSONUtil.parseObj(resultStr);

            result.setStatusOK(true);
            result.setData(jsonObject);
        }

        return result;
    }
}
